package com.hzlj.position.locate.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.fz.common.base.core.date.DateUtils;
import com.fz.common.dict.annotation.DictConvert;
import com.google.common.collect.Maps;
import com.hzlj.common.message.common.dto.message.MessageNoticeResultDTO;
import com.hzlj.common.message.common.util.MessageRestUtil;
import com.hzlj.position.config.common.dto.common.PositionHandleExtDTO;
import com.hzlj.position.config.service.NoticeConfigService;
import com.hzlj.position.locate.common.common.PositionSimpleDTO;
import com.hzlj.position.locate.common.dto.position.PositionCorrectDTO;
import com.hzlj.position.locate.common.dto.position.PositionExtDTO;
import com.hzlj.position.locate.common.dto.reportInspection.ReportInspectionNoticeDTO;
import com.hzlj.position.locate.common.dto.reportInspectionCorrect.ReportInspectionCorrectManualDTO;
import com.hzlj.position.locate.common.dto.reportInspectionCorrectConfig.ReportInspectionCorrectConfigUpsertDTO;
import com.hzlj.position.locate.common.enums.PositionCorrectStatus;
import com.hzlj.position.locate.common.model.Position;
import com.hzlj.position.locate.common.model.ReportInspectionCorrectConfig;
import com.hzlj.position.locate.dao.PositionDao;
import com.hzlj.position.locate.dao.ReportInspectionCorrectConfigDao;
import com.hzlj.position.locate.service.ReportInspectionCorrectConfigService;
import com.hzlj.position.locate.service.ReportInspectionCorrectService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.Map;

/**
 * 通信联络核查-核查-纠偏(ReportInspectionCorrect)表服务接口
 *
 * @author lifh
 * @date 2023-07-26 14:55:07
 */
@Slf4j
@Service
public class ReportInspectionCorrectServiceImpl implements ReportInspectionCorrectService {
    @Resource
    private ReportInspectionCorrectConfigService reportInspectionCorrectConfigService;
    @Resource
    private PositionDao positionDao;
    @Resource
    private ReportInspectionCorrectConfigDao reportInspectionCorrectConfigDao;
    @Resource
    private NoticeConfigService noticeConfigService;

    @Override
    @DictConvert
    public PositionCorrectDTO getPositionCorrect(String positionId, Date positionTime) {
        PositionExtDTO positionExt = positionDao.getPositionExt(positionId, positionTime);
        PositionCorrectDTO result = PositionCorrectDTO.from(positionExt);
        if (result == null || ObjectUtil.isEmpty(result.getCorrectConfigId())) {
            return result;
        }
        //设置处理人
        ReportInspectionCorrectConfig config = this.reportInspectionCorrectConfigDao.getById(result.getCorrectConfigId());
        if (config != null) {
            result.setHandleTime(config.getCreateTime());
            PositionHandleExtDTO ext = new PositionHandleExtDTO();
            ext.setHandlerUid(config.getCreatorUid());
            ext.setHandlerName(config.getCreatorName());
            result.setHandleExt(ext);
        }
        return result;
    }

    /**
     * 发起纠偏
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public MessageNoticeResultDTO send(String positionId, Date positionTime, ReportInspectionNoticeDTO notice) {
        PositionCorrectStatus correctStatus = PositionCorrectStatus.SEND_NOTICE;
        PositionExtDTO positionExt = positionDao.getPositionExt(positionId, positionTime);
        positionExt.setCorrectOriginalPosition(
                PositionSimpleDTO.from(positionDao.getPosition(positionId, positionTime))
        );
        //修改标记
        positionDao.updateCorrectStatus(
                positionId,
                positionTime,
                correctStatus,
                positionExt);

        //拼接消息体参数
        Map<String, Object> noticeParams = Maps.newHashMap();
        noticeParams.put("spotCheckTime", DateUtils.formatDate(new Date()));
        //发送通知
        return MessageRestUtil.noticeQueryUsers(
                "report-inspection-correct",
                notice.getId(),
                noticeParams,
                false,
                notice.getJzId()
        );

    }

    /**
     * 位置上报
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void report(String positionId, Date positionTime, PositionSimpleDTO locate) {
        PositionCorrectStatus correctStatus = PositionCorrectStatus.REPORT;
        PositionExtDTO positionExt = positionDao.getPositionExt(positionId, positionTime);
        positionExt.setCorrectReportPosition(locate);
        //修改标记
        positionDao.updateCorrectStatus(
                positionId,
                positionTime,
                correctStatus,
                positionExt);
    }

    /**
     * 手工纠偏
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void correct(ReportInspectionCorrectManualDTO dto) {
        PositionSimpleDTO correctOriginalPosition = dto.getCorrectOriginalPosition();
        PositionSimpleDTO correctPosition = dto.getCorrectPosition();
        PositionCorrectStatus correctStatus = PositionCorrectStatus.MANUAL_COMPLETE;
        PositionExtDTO positionExt = positionDao.getPositionExt(dto.getPositionId(), dto.getPositionTime());

        //保存或者更新配置
        ReportInspectionCorrectConfigUpsertDTO correctConfig = new ReportInspectionCorrectConfigUpsertDTO();
        correctConfig.setJzId(dto.getJzId());
        correctConfig.setId(positionExt.getCorrectConfigId());
        correctConfig.setCorrectOriginalPosition(
                new PositionSimpleDTO(correctOriginalPosition.getLongitude(), correctOriginalPosition.getLatitude(), correctOriginalPosition.getPosition())
        );
        correctConfig.setCorrectPosition(
                new PositionSimpleDTO(correctPosition.getLongitude(), correctPosition.getLatitude(), correctPosition.getPosition())
        );
        //处理人信息
        correctConfig.setCreateTime(dto.getHandleTime());
        if (dto.getHandleExt() != null) {
            correctConfig.setCreatorUid(dto.getHandleExt().getHandlerUid());
            correctConfig.setCreatorName(dto.getHandleExt().getHandlerName());
        }
        String correctConfigId = this.reportInspectionCorrectConfigService.saveReportInspectionCorrectConfig(correctConfig);

        positionExt.setCorrectOriginalPosition(correctOriginalPosition);
        positionExt.setCorrectPosition(correctPosition);
        positionExt.setCorrectConfigId(correctConfigId);
        //修改标记
        positionDao.updateCorrectStatus(
                dto.getPositionId(),
                dto.getPositionTime(),
                correctStatus,
                positionExt,
                dto.getHandleTime(),
                dto.getHandleExt());
    }

    /**
     * 自动纠偏
     */
    @Override
    public void correct(Position position) {
        if (ObjectUtil.hasEmpty(position.getLongitude(), position.getLatitude())//有位置
                || !noticeConfigService.correctNotice(position.getJgCode())) {//需要纠偏
            return;
        }
        //匹配
        PositionSimpleDTO config = reportInspectionCorrectConfigService.match(position.getJzId(), position.getLongitude(), position.getLatitude());
        if (config == null) {
            return;
        }
        PositionCorrectStatus correctStatus = PositionCorrectStatus.SYSTEM_COMPLETE;

        //修改位置+状态
        PositionExtDTO positionExt = position.getPositionExt();
        if (positionExt == null) {
            positionExt = new PositionExtDTO();
        }
        positionExt.setCorrectOriginalPosition(PositionSimpleDTO.from(position));
        positionExt.setCorrectPosition(
                new PositionSimpleDTO(position.getId(), config.getLongitude(), config.getLatitude(), config.getPosition(), position.getPositionTime())
        );
        position.setCorrectStatus(correctStatus.getCode());
        position.setLatitude(config.getLatitude());
        position.setLongitude(config.getLongitude());
        position.setPosition(config.getPosition());
        position.setPositionExt(positionExt);

        log.info("系统自动纠偏:positoinId={},configId={},priginalPosition={},correctPosition={}",
                position.getId(), positionExt.getCorrectConfigId(), positionExt.getCorrectOriginalPosition(), positionExt.getCorrectPosition());
    }

}
